From 5dc2655e892b3da66844f09b639e8fdaf5b6f35d Mon Sep 17 00:00:00 2001 From: "cl349@freefall.cl.cam.ac.uk" Date: Tue, 9 Nov 2004 13:14:11 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.398 (4190c2a3yFTT9r-Ede8ilkq-wZrXkg) Add focus to pirqs and interdomain evtchns. --- xen/arch/x86/irq.c | 17 +++++++++-------- xen/common/event_channel.c | 26 ++++++++++++++++---------- xen/include/xen/event.h | 11 +++++------ xen/include/xen/irq.h | 3 ++- xen/include/xen/sched.h | 4 ++-- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 32fa237747..0e4f286938 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -188,22 +188,22 @@ typedef struct { u8 nr_guests; u8 in_flight; u8 shareable; - struct domain *guest[IRQ_MAX_GUESTS]; + struct exec_domain *guest[IRQ_MAX_GUESTS]; } irq_guest_action_t; static void __do_IRQ_guest(int irq) { irq_desc_t *desc = &irq_desc[irq]; irq_guest_action_t *action = (irq_guest_action_t *)desc->action; - struct domain *d; + struct exec_domain *ed; int i; for ( i = 0; i < action->nr_guests; i++ ) { - d = action->guest[i]; - if ( !test_and_set_bit(irq, &d->pirq_mask) ) + ed = action->guest[i]; + if ( !test_and_set_bit(irq, &ed->domain->pirq_mask) ) action->in_flight++; - send_guest_pirq(d, irq); + send_guest_pirq(ed, irq); } } @@ -235,8 +235,9 @@ int pirq_guest_unmask(struct domain *d) return 0; } -int pirq_guest_bind(struct domain *d, int irq, int will_share) +int pirq_guest_bind(struct exec_domain *ed, int irq, int will_share) { + struct domain *d = ed->domain; irq_desc_t *desc = &irq_desc[irq]; irq_guest_action_t *action; unsigned long flags; @@ -296,7 +297,7 @@ int pirq_guest_bind(struct domain *d, int irq, int will_share) goto out; } - action->guest[action->nr_guests++] = d; + action->guest[action->nr_guests++] = ed; out: spin_unlock_irqrestore(&desc->lock, flags); @@ -330,7 +331,7 @@ int pirq_guest_unbind(struct domain *d, int irq) else { i = 0; - while ( action->guest[i] != d ) + while ( action->guest[i] && action->guest[i]->domain != d ) i++; memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1); action->nr_guests--; diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index dd1c49b194..d8e7c9b9eb 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -96,6 +96,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) { #define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 ) struct domain *d1, *d2; + struct exec_domain *ed1, *ed2; int port1 = bind->port1, port2 = bind->port2; domid_t dom1 = bind->dom1, dom2 = bind->dom2; long rc = 0; @@ -119,6 +120,9 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) return -ESRCH; } + ed1 = d1->exec_domain[0]; /* XXX */ + ed2 = d2->exec_domain[0]; /* XXX */ + /* Avoid deadlock by first acquiring lock of domain with smaller id. */ if ( d1 < d2 ) { @@ -167,7 +171,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) break; case ECS_INTERDOMAIN: - if ( d1->event_channel[port1].u.interdomain.remote_dom != d2 ) + if ( d1->event_channel[port1].u.interdomain.remote_dom != ed2 ) ERROR_EXIT(-EINVAL); if ( (d1->event_channel[port1].u.interdomain.remote_port != port2) && (bind->port2 != 0) ) @@ -193,7 +197,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) break; case ECS_INTERDOMAIN: - if ( d2->event_channel[port2].u.interdomain.remote_dom != d1 ) + if ( d2->event_channel[port2].u.interdomain.remote_dom != ed1 ) ERROR_EXIT(-EINVAL); if ( (d2->event_channel[port2].u.interdomain.remote_port != port1) && (bind->port1 != 0) ) @@ -209,11 +213,11 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) * Everything checked out okay -- bind to . */ - d1->event_channel[port1].u.interdomain.remote_dom = d2; + d1->event_channel[port1].u.interdomain.remote_dom = ed2; d1->event_channel[port1].u.interdomain.remote_port = (u16)port2; d1->event_channel[port1].state = ECS_INTERDOMAIN; - d2->event_channel[port2].u.interdomain.remote_dom = d1; + d2->event_channel[port2].u.interdomain.remote_dom = ed1; d2->event_channel[port2].u.interdomain.remote_port = (u16)port1; d2->event_channel[port2].state = ECS_INTERDOMAIN; @@ -284,7 +288,7 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind) goto out; d->pirq_to_evtchn[pirq] = port; - rc = pirq_guest_bind(d, pirq, + rc = pirq_guest_bind(current, pirq, !!(bind->flags & BIND_PIRQ__WILL_SHARE)); if ( rc != 0 ) { @@ -346,7 +350,7 @@ static long __evtchn_close(struct domain *d1, int port1) case ECS_INTERDOMAIN: if ( d2 == NULL ) { - d2 = chn1[port1].u.interdomain.remote_dom; + d2 = chn1[port1].u.interdomain.remote_dom->domain; /* If we unlock d1 then we could lose d2. Must get a reference. */ if ( unlikely(!get_domain(d2)) ) @@ -370,7 +374,7 @@ static long __evtchn_close(struct domain *d1, int port1) goto again; } } - else if ( d2 != chn1[port1].u.interdomain.remote_dom ) + else if ( d2 != chn1[port1].u.interdomain.remote_dom->domain ) { rc = -EINVAL; goto out; @@ -383,7 +387,7 @@ static long __evtchn_close(struct domain *d1, int port1) BUG(); if ( chn2[port2].state != ECS_INTERDOMAIN ) BUG(); - if ( chn2[port2].u.interdomain.remote_dom != d1 ) + if ( chn2[port2].u.interdomain.remote_dom->domain != d1 ) BUG(); chn2[port2].state = ECS_UNBOUND; @@ -433,7 +437,8 @@ static long evtchn_close(evtchn_close_t *close) static long evtchn_send(int lport) { - struct domain *ld = current->domain, *rd; + struct domain *ld = current->domain; + struct exec_domain *rd; int rport; spin_lock(&ld->event_channel_lock); @@ -494,7 +499,8 @@ static long evtchn_status(evtchn_status_t *status) break; case ECS_INTERDOMAIN: status->status = EVTCHNSTAT_interdomain; - status->u.interdomain.dom = chn[port].u.interdomain.remote_dom->id; + status->u.interdomain.dom = + chn[port].u.interdomain.remote_dom->domain->id; status->u.interdomain.port = chn[port].u.interdomain.remote_port; break; case ECS_PIRQ: diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 517b22ed4d..168c28185d 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -20,9 +20,9 @@ * may require explicit memory barriers. */ -static inline void evtchn_set_pending(struct domain *d, int port) +static inline void evtchn_set_pending(struct exec_domain *ed, int port) { - struct exec_domain *ed = d->exec_domain[0]; + struct domain *d = ed->domain; shared_info_t *s = d->shared_info; int running; @@ -57,8 +57,7 @@ static inline void evtchn_set_pending(struct domain *d, int port) */ static inline void send_guest_virq(struct exec_domain *ed, int virq) { - struct domain *d = ed->domain; - evtchn_set_pending(d, d->virq_to_evtchn[virq]); + evtchn_set_pending(ed, ed->domain->virq_to_evtchn[virq]); } /* @@ -66,9 +65,9 @@ static inline void send_guest_virq(struct exec_domain *ed, int virq) * @d: Domain to which physical IRQ should be sent * @pirq: Physical IRQ number */ -static inline void send_guest_pirq(struct domain *d, int pirq) +static inline void send_guest_pirq(struct exec_domain *ed, int pirq) { - evtchn_set_pending(d, d->pirq_to_evtchn[pirq]); + evtchn_set_pending(ed, ed->domain->pirq_to_evtchn[pirq]); } #define event_pending(_d) \ diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h index 06233dddd2..efd8f77125 100644 --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -65,8 +65,9 @@ extern hw_irq_controller no_irq_type; extern void no_action(int cpl, void *dev_id, struct xen_regs *regs); struct domain; +struct exec_domain; extern int pirq_guest_unmask(struct domain *p); -extern int pirq_guest_bind(struct domain *p, int irq, int will_share); +extern int pirq_guest_bind(struct exec_domain *p, int irq, int will_share); extern int pirq_guest_unbind(struct domain *p, int irq); extern int pirq_guest_bindable(int irq, int will_share); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 17e58f6337..2c28a4a639 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -42,8 +42,8 @@ typedef struct event_channel_st domid_t remote_domid; } __attribute__ ((packed)) unbound; /* state == ECS_UNBOUND */ struct { - u16 remote_port; - struct domain *remote_dom; + u16 remote_port; + struct exec_domain *remote_dom; } __attribute__ ((packed)) interdomain; /* state == ECS_INTERDOMAIN */ u16 pirq; /* state == ECS_PIRQ */ u16 virq; /* state == ECS_VIRQ */ -- 2.30.2